package com.l.im.server;


import com.l.im.common.config.ConfigReader;
import com.l.im.handler.HttpRequestHandler;
import com.l.im.init.HttpGatewayInitializer;
import com.l.im.init.ZookeeperConnector;
import com.l.im.strategy.RandomRouteStrategy;
import com.l.im.strategy.RouteStrategy;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.ArrayList;
import java.util.List;

/**
 * @program: LIM
 * @description:
 * @author: Alex Wu
 * @createDate: 2025-04-14 18:00
 **/
@Slf4j
public class HttpGatewayServer {

    private final int port;
    private final ZookeeperConnector zookeeperConnector;
    private List<String> servers = new ArrayList<>();

    public HttpGatewayServer(int port) throws Exception {
        this.port = port;
        // 连接到 ZooKeeper
        CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient(
                ConfigReader.getInstance().getOrDefault("zookeeper.address",String.class,""),
                new ExponentialBackoffRetry(1000, 3));
        curatorFramework.start();
        this.zookeeperConnector = new ZookeeperConnector(curatorFramework);

        // 监听 /ws/nodes/ 路径
        zookeeperConnector.watchNodes("/ws/nodes", (client, event) -> {

            if (event.getType() == PathChildrenCacheEvent.Type.CHILD_ADDED || event.getType() == PathChildrenCacheEvent.Type.CHILD_REMOVED) {
                updateServerList();
            }
        });
    }

    // 更新服务器列表
    private void updateServerList() throws Exception {
        List<String> newServers = new ArrayList<>();
        List<String> nodePaths = zookeeperConnector.getCuratorFramework().getChildren().forPath("/ws/nodes");

        for (String path : nodePaths) {
            newServers.add(path);
        }

        servers = newServers;
    }

    public void start() throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            // 使用随机路由策略
            RouteStrategy routeStrategy = new RandomRouteStrategy();

            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new HttpGatewayInitializer(routeStrategy, servers));

            Channel ch = b.bind(port).sync().channel();
            log.info("HTTP Gateway Server started at http://127.0.0.1:" + port);
            ch.closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}
